<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/model/DAO/mysql/DataBase.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/model/DAO/PostDAO.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/entities/Entity.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/entities/Post.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/entities/Person.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/exceptions/DataBaseException.php';

/**
 * Класс для работы с должностями в БД
 */
class PostDAOImpl extends PostDAO {

	/**
	 * Метод, отвечающий за создание новой записи в БД
	 */
	public function create(Entity $post) {
		/*
		 $sql = 'INSERT INTO `post` (`name`,`is_unique`) ';
		$sql .= 'VALUES ("'.$post->getName().'",';
				$sql .= (int)($post->isUnique()).')';
		try {
		$this->query($sql);
		$post->setIdentity($this->identity());
		return $post;
		} catch(DataBaseException $exception) {
		return null;
		}
		*/
		$name = $post->getName();
		$isUnique = (int)($post->isUnique());

		$stmt = $this->dbh->connection->prepare('INSERT INTO `post` (`name`, `is_unique`) VALUES (?, ?)');
		$stmt->bindValue(1, $name);
		$stmt->bindValue(2, $isUnique);

		try {
			$this->dbh->query($stmt);
			$post->setIdentity($this->dbh->identity());
			return $post;
		} catch (PDOException $exception) {
			return null;
		}
	}

	/**
	 * Метод, отвечающий за чтение записи из БД
	 */
	public function read($identity) {
		/*		$posts = $this->build('`id`='.((int)$identity));
		 if(count($posts) == 1) {
		return $posts[0];
		} else {
		return null;
		}
		*/

		$id = ((int)$identity);
		$params = array("1"=>$id);

		$posts = $this->build('`id`=?',$params);
		if(count($posts) == 1) {
			return $posts[0];
		} else {
			return null;
		}

	}

	/**
	 * Метод, отвечающий за обновление записи в БД
	 */
	public function update(Entity $post) {
		/*		$sql = 'UPDATE `post` ';
		 $sql .= 'SET `name`="'.$post->getName().'",';
		$sql .= '`is_unique`='.(int)($post->isUnique()).' ';
		$sql .= 'WHERE `id`='.$post->getIdentity();
		try {
		$this->query($sql);
		return $post;
		} catch(DataBaseException $exception) {
		return null;
		}
		*/
		$name = $post->getName();
		$isUnique = (int)($post->isUnique());
		$id = $post->getIdentity();

		$stmt = $this->dbh->connection->prepare('UPDATE `post` SET `name`=?, `is_unique`=? WHERE `id`=?');
		$stmt->bindValue(1, $name);
		$stmt->bindValue(2, $isUnique);
		$stmt->bindValue(3, $id);

		try {
			$this->dbh->query($stmt);
			return $post;
		} catch (PDOException $exception) {
			return null;
		}
	}

	/**
	 * Метод, отвечающий за удаление записи из БД
	 * @param $identity Уникальный идентификатор
	 */
	public function delete($identity) {
		/*		$sql = 'DELETE FROM `post` ';
		 $sql .= 'WHERE `id`='.((int)$identity);
		try {
		$this->query($sql);
		return true;
		} catch(DataBaseException $exception) {
		return false;
		}
		*/
		$id = (int)($identity);

		$stmt = $this->dbh->connection->prepare('DELETE FROM `post` WHERE `id`=?');
		$stmt->bindValue(1, $id);

		try {
			$this->dbh->query($stmt);
			return true;
		} catch (PDOException $exception) {
			return false;
		}
	}

	/**
	 * Метод, получающий список всех должностей из БД
	 */
	public function getAll() {
		return $this->build(null,null);
	}

	/**
	 * Метод, получающий уникальные должности
	 */
	public function getUniquePosts() {
		/*
		 $sql = 'SELECT `post`.`id` ';
		$sql .= 'FROM `post` ';
		$sql .= 'WHERE `post`.`is_unique`=1 ';
		return $this->build('`id` IN ('.$sql.')');
		*/

		$params = array("1"=>'SELECT `post`.`id` FROM `post` WHERE `post`.`is_unique`=1');
		return $this->build('`id` IN (?)',$params);

	}

	/**
	 * Метод, получающий список свободных должностей
	 */
	public function getFreePosts(Person $person) {
		/*
		 $sql = 'SELECT `post`.`id` ';
		$sql .= 'FROM `post` INNER JOIN `employee` ON `post`.`id`=`employee`.`id_post` ';
		$sql .= 'WHERE `post`.`is_unique`=1 OR `employee`.`id_person`='.$person->getIdentity();
		return $this->build('`id` NOT IN ('.$sql.')');
		*/

		$id = $person->getIdentity();
		$params = array("1"=>$id);
		return $this->build('`id` NOT IN (SELECT `post`.`id` FROM `post` INNER JOIN `employee` ON `post`.`id`=`employee`.`id_post` WHERE `post`.`is_unique`=1 OR `employee`.`id_person`=?)',$params);

	}

	/**
	 * Создает массив экземпляров класса Post на основе SQL-запроса на выборку
	 * с условием $condition
	 */
	private function build($condition,$params) {
		/*		$posts = array();
		 $sql = 'SELECT `id`,`name`,`is_unique` ';
		$sql .= 'FROM `post`';
		if($condition !== null) {
		$sql .= ' WHERE '.$condition;
		}
		$this->query($sql);
		while($row = $this->row()) {
		$post = new Post();
		$post->setIdentity($row['id']);
		$post->setName($row['name']);
		$post->setUnique($row['is_unique']);
		$posts[] = $post;
		}
		$this->close();
		return $posts;
		*/

		$sql = 'SELECT `id`, `name`, `is_unique` FROM `post`';
		if($condition !== null) {
			$sql = 'SELECT `id`, `name`, `is_unique` FROM `post` WHERE '.$condition;
			$stmt = $this->dbh->connection->prepare($sql);
			if($condition !== null) {
				foreach ($params as $i=>$value){
					$stmt->bindValue($i, $value);
				}
			}
			$this->dbh->query($stmt);
		}else{
			$this->dbh->execute($sql);
		}
		$posts = array();
		while($row = $this->dbh->row()) {
			$post = new Post();
			$post->setIdentity($row['id']);
			$post->setName($row['name']);
			$post->setUnique($row['is_unique']);
			$posts[] = $post;
		}
		$this->dbh->close($stmt);
		return $posts;
	}

}
?>